package com.apple1.blogweb.config;
 
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import com.apple1.blogdao.RoleMapper;
import com.apple1.blogdao.UserMapper;
import com.apple1.blogentity.Permission;
import com.apple1.blogentity.form.RoleForm;
import com.apple1.blogentity.form.UserForm;

import lombok.extern.slf4j.Slf4j;
 
/**
 * Created by Administrator on 2017/12/11.
 * 自定义权限匹配和账号密码匹配
 */
@Slf4j
public class MyShiroRealm extends AuthorizingRealm {

	@Autowired
	private UserMapper userMapper;
	@Autowired
	private RoleMapper roleMapper;
	@Value("${shiro.role}")
	private String role;
	
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        log.info("MyShiroRealm.doGetAuthorizationInfo():权限配置");
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        UserForm userInfo = (UserForm) principals.getPrimaryPrincipal();
        for (RoleForm role : userInfo.getRoles()) {
            authorizationInfo.addRole(role.getRoleName());
            for (Permission p : role.getPermissions()) {
                authorizationInfo.addStringPermission(p.getUrl());
            }
        }
        return authorizationInfo;
    }
 
    /*主要是用来进行身份认证的，也就是说验证用户输入的账号和密码是否正确。*/
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token)
            throws AuthenticationException {
    	log.info("MyShiroRealm.doGetAuthenticationInfo():身份认证");
//        System.out.println("MyShiroRealm.doGetAuthenticationInfo()");
        //获取用户的输入的账号.
        String userName = (String) token.getPrincipal();
//        System.out.println(token.getCredentials());
        //通过username从数据库中查找 User对象，如果找到，没找到.
        //实际项目中，这里可以根据实际情况做缓存，如果不做，Shiro自己也是有时间间隔机制，2分钟内不会重复执行该方法
        UserForm userInfo = userMapper.selectByPrimaryKey(userName);
        if (userInfo == null || userInfo.getStatus() == 3) {
            return null;
        }
        if(userInfo.getStatus() == null || userInfo.getStatus() == 1) {
        	throw new LockedAccountException();
        }
        //是包含预设的角色赋予全部角色权限
        for(RoleForm shiroRole : userInfo.getRoles()) {
            if(shiroRole.getRoleName().equals(role)) {
            	userInfo.setRoles(roleMapper.selectAll());
            	break;
            }
        }

        

        //密码加密后对比
        SimpleAuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(
                userInfo, //用户名
                userInfo.getPassword(), //密码
                ByteSource.Util.bytes(""),//salt=username+salt
                getName()  //realm name
        );
        return authenticationInfo;
    }
 
}
